package com.skyk.config.interceptor;

import com.skyk.util.context.UserContext;
import com.skyk.pojo.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//自定义拦截器:   在请求到达Controller之前调用

/*1.服务器接收到请求后，从请求头中提取SessionKey*/
/*2.服务器使用SessionKey在服务器端的存储中查找对应的用户信息*/
/*3.如果找到了对应的用户信息，服务器将用户信息存储到ThreadLocal中，以便在后续的方法中使用*/
/*4.如果没有找到对应的用户信息（例如，Session已过期或被删除），服务器将返回适当的错误响应*/


@Component  //允许 Spring 自动检测自定义 Bean
@Slf4j
public class SessionKeyInterceptor implements HandlerInterceptor {

    /**/
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    //调用Controller之前执行
    //如果返回 true --- 拦截器验证成功，继续执行后面的方法
    //如果返回 false --- 拦截器验证失败，终止后续流程
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //在请求头中获取前端请求时携带的sessionKey
        String sessionKey = request.getHeader("SessionKey");
        log.info("当前用户的sessionKey:" + sessionKey);

        if (sessionKey != null && !sessionKey.isEmpty()) {
            //在Reids中，根据sessionKey查询用户信息
            User user = (User) redisTemplate.opsForValue().get(sessionKey);

            if (user != null) {
                //如果查询到用户信息，就将用户信息存储到ThreadLocal中
                UserContext.setUser(user);
                return true; //继续请求处理
            } else {
                //用户信息未查询到时，响应给前端错误信息
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);  //未授权
                return false; //阻止请求处理
            }
        } else {
            //前端请求时未携带sessionKey时,服务器给前端响应错误信息
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST); //缺少sessionKey
            return false; //阻止请求处理
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserContext.clear();//清理ThreadLocal中的用户信息
    }
}
